package me.chnxan.core;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import me.chnxan.util.ReflectionUtil;

/**
 * @author JH
 * @author XC
 * @since 2011-12-02
 * 
 * @param <T>
 * @param <PK>
 */
public abstract class EntityAtomManager<T extends ModelAtom, PK extends Serializable> {

	protected Logger logger = LoggerFactory.getLogger(getClass());

	protected Class<T> entityClass;// 泛型所指定的Class 类型，用于hibernate 查询时使用

	@Autowired
	private HibernateCaller hibernateCaller;

	public HibernateCaller getHibernateCaller() {
		return hibernateCaller;
	}

	public void setHibernateCaller(HibernateCaller hibernateCaller) {
		this.hibernateCaller = hibernateCaller;
	}

	public EntityAtomManager() {
		this.entityClass = ReflectionUtil.getSuperClassGenricType(getClass());
	}

	// ==============================================================
	/**
	 * 批量保存
	 * 
	 * 实体对象以List的方式传递，循环进行删除
	 * 
	 * @param list
	 */
	public void save(List<T> list) {
		for (T entity : list) {
			save(entity);
		}
	}

	public void save(final T entity) {
		getHibernateCaller().saveOrUpdateObject(entity);
	}

	public void deleteEntity(final T entity) {
		getHibernateCaller().removeObject(entity);
	}

	/**
	 * 通过修改 isValid 有效性标识，来删除数据，而不是直接从数据库删除
	 * 
	 * @param entity
	 */
	public void delete(final T entity) {
		entity.setIsValid(false);
		save(entity);
	}

	/**
	 * @see delete(final T entity)
	 * 
	 * @param id
	 */
	public void delete(final PK id) {
		T entity = get(id);
		delete(entity);
	}

	/**
	 * 通过ID 查询获取 实体对象 默认为有效对象
	 * 
	 * @param id
	 * @return
	 */
	public T get(final PK id) {
		return get(id, true);
	}

	/**
	 * 通过ID 查询获取 实体对象
	 * 
	 * @param id
	 * @return
	 */
	public T get(final PK id, boolean isValid) {
		T t = (T) hibernateCaller.getObject(entityClass, id);
		if (t != null && ((isValid && t.getIsValid()) || !isValid))
			return t;
		return null;
	}

	/**
	 * 指定 属性查询，返回唯一对象
	 * 
	 * @param propertyName
	 * @param value
	 * @return
	 */
	public T getUnique(String propertyName, Object value) {
		return (T) getHibernateCaller().findUnique(entityClass, propertyName,
				value);
	}

	public T getUnique(String[] propertyName, Object[] value) {
		return (T) getHibernateCaller().findUnique(entityClass, propertyName,
				value);
	}

	/**
	 * 按单个属性进行查询 默认返回有效对象
	 * 
	 * @param propertyName
	 * @param value
	 * @return
	 */
	public List<T> get(String propertyName, Object value) {
		return get(propertyName, value, true);
	}

	/**
	 * 按单个属性进行查询
	 * 
	 * @param propertyName
	 * @param value
	 * @return
	 */
	public List<T> get(String propertyName, Object value, boolean isValid) {
		List<T> list = hibernateCaller.find(entityClass, propertyName, value);
		if (isValid) {
			List<T> temp = new ArrayList<T>();
			for (T t : list) {
				if (t.getIsValid())
					temp.add(t);
			}
			return temp;
		}
		return list;
	}

	/**
	 * 按多个属性查询 默认返回有效对象
	 * 
	 * @param propertyName
	 * @param value
	 * @return
	 */
	public List<T> get(String[] propertyName, Object[] value) {
		return get(propertyName, value, true);
	}

	/**
	 * 按多个属性查询
	 * 
	 * @param propertyName
	 * @param value
	 * @return
	 */
	public List<T> get(String[] propertyName, Object[] value, boolean isValid) {
		List<T> list = getHibernateCaller().find(entityClass, propertyName,
				value);
		if (isValid) {
			List<T> temp = new ArrayList<T>();
			for (T t : list) {
				if (t.getIsValid())
					temp.add(t);
			}
			return temp;
		}
		return list;
	}

	/**
	 * Search by hql
	 * 
	 * @param hql
	 * @param values
	 * @return
	 */
	public List<T> find(String hql, Object... values) {
		return getHibernateCaller().find(hql, values);
	}

	/**
	 * Search by hql in condition
	 * 
	 * @param hql
	 * @param values
	 * @return
	 */
	public List<T> find(String hql, String paraName, Object[] values) {
		return getHibernateCaller().find(hql, paraName, values);
	}

	/**
	 * Remove by hql
	 * 
	 * @param hql
	 * @param values
	 * @return
	 */
	public void remove(String hql, Object... values) {
		getHibernateCaller().remove(hql, values);
	}

	/**
	 * Remove by hql
	 * 
	 * @param hql
	 * @param values
	 * @return
	 */
	public void update(String hql, Object... values) {
		getHibernateCaller().update(hql, values);
	}

	/**
	 * 按page 分页查询
	 * 
	 * @param page
	 * @param hql
	 * @param values
	 *            Object...
	 * @return
	 */
	public Page<T> search(final Page<T> page, String hql, Object... values) {
		return getHibernateCaller().find(entityClass, page, hql, values);
	}

	/**
	 * 按page 分页查询
	 * 
	 * @param page
	 * @param chql
	 *            count hql
	 * @param hql
	 * @param values
	 *            Object...
	 * @return
	 */
	public Page<T> search(final Page<T> page, String chql, String hql,
			Object... values) {
		return getHibernateCaller().find(entityClass, page, chql, hql, values);
	}

	/**
	 * 按page 分页查询
	 * 
	 * @param page
	 * @param filters
	 * @return
	 */
	public Page<T> search(final Page<T> page, final List<PropertyFilter> filters) {
		return getHibernateCaller().find(entityClass, page, filters);
	}
}
